#include <common.h>
#include <stdio.h>

#include <asm/io.h>

#define PCIIO_BASE        CKSEG1ADDR(0x18000000)

#define OFFSET_2E_4E          0x20

#define NS16550_DATA          0
#define NS16550_IER           1
#define NS16550_IIR           2
#define NS16550_FIFO          2
#define NS16550_CFCR          3
#define NS16550_MCR           4
#define NS16550_LSR           5
#define NS16550_MSR           6
#define NS16550_SCR           7
#define NSREG(x)             (x)


/* interrupt enable register */
#define IER_ERXRDY      0x1 /* int on rx ready */
#define IER_ETXRDY      0x2 /* int on tx ready */
#define IER_ERLS        0x4 /* int on line status change */
#define IER_EMSC        0x8 /* int on modem status change */

/* interrupt identification register */
#define IIR_IMASK       0xf /* mask */
#define IIR_RXTOUT      0xc /* receive timeout */
#define IIR_RLS         0x6 /* receive line status */
#define IIR_RXRDY       0x4 /* receive ready */
#define IIR_TXRDY       0x2 /* transmit ready */
#define IIR_NOPEND      0x1 /* nothing */
#define IIR_MLSC        0x0 /* modem status */
#define IIR_FIFO_MASK   0xc0  /* set if FIFOs are enabled */

/* fifo control register */
#define FIFO_ENABLE     0x01  /* enable fifo */
#define FIFO_RCV_RST    0x02  /* reset receive fifo */
#define FIFO_XMT_RST    0x04  /* reset transmit fifo */
#define FIFO_DMA_MODE   0x08  /* enable dma mode */
#define FIFO_TRIGGER_1  0x00  /* trigger at 1 char */
#define FIFO_TRIGGER_4  0x40  /* trigger at 4 chars */
#define FIFO_TRIGGER_8  0x80  /* trigger at 8 chars */
#define FIFO_TRIGGER_14 0xc0  /* trigger at 14 chars */

/* character format control register */
#define CFCR_DLAB       0x80  /* divisor latch */
#define CFCR_SBREAK     0x40  /* send break */
#define CFCR_PZERO      0x30  /* zero parity */
#define CFCR_PONE       0x20  /* one parity */
#define CFCR_PEVEN      0x10  /* even parity */
#define CFCR_PODD       0x00  /* odd parity */
#define CFCR_PENAB      0x08  /* parity enable */
#define CFCR_STOPB      0x04  /* 2 stop bits */
#define CFCR_8BITS      0x03  /* 8 data bits */
#define CFCR_7BITS      0x02  /* 7 data bits */
#define CFCR_6BITS      0x01  /* 6 data bits */
#define CFCR_5BITS      0x00  /* 5 data bits */

/* modem control register */
#define MCR_LOOPBACK    0x10  /* loopback */
#define MCR_IENABLE     0x08  /* output 2 = int enable */
#define MCR_DRS         0x04  /* output 1 = xxx */
#define MCR_RTS         0x02  /* enable RTS */
#define MCR_DTR         0x01  /* enable DTR */

/* line status register */
#define LSR_RCV_FIFO    0x80  /* error in receive fifo */
#define LSR_TSRE        0x40  /* transmitter empty */
#define MSR_DSR         0x20  /* DSR active */
#define MSR_CTS         0x10  /* CTS active */
#define MSR_DDCD        0x08    /* DCD changed */
#define MSR_TERI        0x04    /* RI  changed */
#define MSR_DDSR        0x02    /* DSR changed */
#define MSR_DCTS        0x01    /* CTS changed */

// 2E/2F(low) or 4E/4F(high) (Depends on the hardware pin level)
#define NCT6106_REG_EFER  0x2E                  // Extended Function Enable Registers
#define NCT6106_REG_EFDR  (NCT6106_REG_EFER+1)  // Extended Function Data Register
#define NCT6106_REG_EFIR  NCT6106_REG_EFER      // Extended Function Index Register

// logical device number
#define NCT6106_LOGICAL_DEV_NO_FDC         0x00
#define NCT6106_LOGICAL_DEV_NO_PRT         0x01
#define NCT6106_LOGICAL_DEV_NO_UARTA       0x02
#define NCT6106_LOGICAL_DEV_NO_UARTB       0x03
#define NCT6106_LOGICAL_DEV_NO_KBC         0x05
#define NCT6106_LOGICAL_DEV_NO_CIR         0x06
#define NCT6106_LOGICAL_DEV_NO_GPIO1       0x07
#define NCT6106_LOGICAL_DEV_NO_GPIO2       0x08
#define NCT6106_LOGICAL_DEV_NO_GPIO3_WDT1  0x09
#define NCT6106_LOGICAL_DEV_NO_ACPI        0x0A
#define NCT6106_LOGICAL_DEV_NO_HM_LED      0x0B
#define NCT6106_LOGICAL_DEV_NO_WDT2        0x0D
#define NCT6106_LOGICAL_DEV_NO_CIR_WAKEUP  0x0E
#define NCT6106_LOGICAL_DEV_NO_GPIO4       0x0F
#define NCT6106_LOGICAL_DEV_NO_UARTC       0x10
#define NCT6106_LOGICAL_DEV_NO_UARTD       0x11
#define NCT6106_LOGICAL_DEV_NO_UARTE       0x12
#define NCT6106_LOGICAL_DEV_NO_UARTF       0x13
#define NCT6106_LOGICAL_DEV_NO_PORT80_IR   0x14
#define NCT6106_LOGICAL_DEV_NO_FADING_LED  0x15
#define NCT6106_LOGICAL_DEV_NO_DEEP_SLEEP  0x16
#define NCT6106_LOGICAL_DEV_NO_MAX         0x17
#define NCT6106_LOGICAL_DEV_NO_GLOBAL      0xFF

// Global register
#define NCT6106_REG_GLOBAL_SR     0x02  // Software Reset Register
#define NCT6106_REG_GLOBAL_LDS    0x07  // Logical Device Selection
#define NCT6106_REG_GLOBAL_DITS1  0x10  // Device IRQ TYPE Selection
#define NCT6106_REG_GLOBAL_DITS2  0x11  // Device IRQ TYPE Selection
#define NCT6106_REG_GLOBAL_DIPS1  0x13  // Device IRQ Polarity Selection
#define NCT6106_REG_GLOBAL_DIPS2  0x14  // Device IRQ Polarity Selection
#define NCT6106_REG_GLOBAL_MFS1   0x1A  // Multi Function Selection
#define NCT6106_REG_GLOBAL_MFS2   0x1B  // Multi Function Selection
#define NCT6106_REG_GLOBAL_MFS3   0x1C  // Multi Function Selection
#define NCT6106_REG_GLOBAL_CIDH   0x20  // Chip ID ( High Byte )
#define NCT6106_REG_GLOBAL_CIDL   0x21  // Chip ID ( Low Byte )
#define NCT6106_REG_GLOBAL_DPD    0x22  // Device Power Down
#define NCT6106_REG_GLOBAL_MFS_GO 0x24  // Multi Function Selection & Global Option
#define NCT6106_REG_GLOBAL_ITSE   0x25  // Interface Tri-state Enable
#define NCT6106_REG_GLOBAL_GO1    0x26  // Global Option
#define NCT6106_REG_GLOBAL_GO2    0x27  // Global Option
#define NCT6106_REG_GLOBAL_GO3    0x28  // Global Option
#define NCT6106_REG_GLOBAL_GO4    0x29  // Global Option
#define NCT6106_REG_GLOBAL_GO5    0x2A  // Global Option
#define NCT6106_REG_GLOBAL_SFR    0x2F  // Strapping Function Result


//IRQ TYPE SELECT
#define  DITS_VAL_IRQ_TYPE_SELECT_EDGE   0
#define  DITS_VAL_IRQ_TYPE_SELECT_LEVEL  1
//DITS1_BIT
#define  DITS1_BIT_IRQ_TYPE_SELECT_FDC       7
#define  DITS1_BIT_IRQ_TYPE_SELECT_PRT       6
#define  DITS1_BIT_IRQ_TYPE_SELECT_UARTA     5
#define  DITS1_BIT_IRQ_TYPE_SELECT_UARTB     4
#define  DITS1_BIT_IRQ_TYPE_SELECT_KBC       3
#define  DITS1_BIT_IRQ_TYPE_SELECT_MOUSE     2
#define  DITS1_BIT_IRQ_TYPE_SELECT_CIR       1
#define  DITS1_BIT_IRQ_TYPE_SELECT_CIRWAKUP  1
//DITS2_BIT
#define  DITS2_BIT_IRQ_TYPE_SELECT_HM        7
#define  DITS2_BIT_IRQ_TYPE_SELECT_WDTO      6
#define  DITS2_BIT_IRQ_TYPE_SELECT_UARTC     5
#define  DITS2_BIT_IRQ_TYPE_SELECT_UARTD     4
#define  DITS2_BIT_IRQ_TYPE_SELECT_UARTE     3
#define  DITS2_BIT_IRQ_TYPE_SELECT_UARTF     2
#define  DITS2_BIT_IRQ_TYPE_SELECT_SMI       1


//Device IRQ Polarity Selection
//DIPS1:IRQ Channel<15:8>  DIPS1: IRQ Channel<7:0>
#define  DIPS_VAL_HIGH   0
#define  DIPS_VAL_LOW    1


unsigned char Nct6106d_read(unsigned char dev, unsigned char addr)
{
	unsigned char data = 0;
	/* Enter the Extended Function Mode */
	outb(0x87, PCIIO_BASE + NCT6106_REG_EFER);
	outb(0x87, PCIIO_BASE + NCT6106_REG_EFER);

	/* Configure the Configuration Registers */
	if (dev < NCT6106_LOGICAL_DEV_NO_MAX) {
		/*select logic dev */
		outb(0x7, PCIIO_BASE + NCT6106_REG_EFIR);
		outb(dev, PCIIO_BASE + NCT6106_REG_EFDR);
	}

	/* select logic dev reg addr and data */
	outb(addr, PCIIO_BASE + NCT6106_REG_EFIR);
	data = inb(PCIIO_BASE + NCT6106_REG_EFDR);

	/* Exit the Extended Function Mode */
	outb(0xAA, PCIIO_BASE + NCT6106_REG_EFER);

	return data;
}

void Nct6106d_write(unsigned char dev, unsigned char addr, unsigned char data)
{
	/* Enter the Extended Function Mode */
	outb(0x87, PCIIO_BASE + NCT6106_REG_EFER);
	outb(0x87, PCIIO_BASE + NCT6106_REG_EFER);

	/* Configure the Configuration Registers */
	if (dev < NCT6106_LOGICAL_DEV_NO_MAX) {
		/*select logic dev */
		outb(0x7, PCIIO_BASE + NCT6106_REG_EFIR);
		outb(dev, PCIIO_BASE + NCT6106_REG_EFDR);
	}

	/* select logic dev reg addr and data */
	outb(addr, PCIIO_BASE + NCT6106_REG_EFIR);
	outb(data, PCIIO_BASE + NCT6106_REG_EFDR);

	/* Exit the Extended Function Mode */
	outb(0xAA, PCIIO_BASE + NCT6106_REG_EFER);
}


void superio_init(void)
{
	unsigned int data = 0;
	// reset
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_SR, 0x01);

	// Disable URAT A B  legacy mode
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1, 0x03);

	// Disable URAT C D E F  legacy mode
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO4, 0xFF);

	// ps/2
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS1, 0xCC);

	// uartd
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS3, 0x1F);

#if 0
	// Lpc Polarity DEBUG
	(*(volatile unsigned int*)0X90000E0010002010) = 0x0;

	// Must set 1 before  accessing Device IRQ Polarity Selection and Device IRQ TYPE Selection
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1, data|(0x01<<4));

	// Device IRQ Polarity Selection.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DIPS1, 0xFF);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DIPS2, 0xFF);


	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA,0x30,0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA,0x60,0x03); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA,0x61,0xf8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA,0x70,0x04); // select IRQ resource for Serial Port 1.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA,0xf0,0x02); // ART A clock source is 2 MHz (24 MHz / 12)

	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB,0x30,0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB,0x60,0x02); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB,0x61,0xf8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB,0x70,0x03); // select IRQ resource for Serial Port 2.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB,0xf0,0x02); // ART B clock source is 2 MHz (24 MHz / 12)


	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC,0x30,0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC,0x60,0x03); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC,0x61,0xe8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC,0x70,0x05); // select IRQ resource for Serial Port 3.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC,0xf0,0x02); // ART C clock source is 2 MHz (24 MHz / 12)


	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD,0x30,0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD,0x60,0x02); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD,0x61,0xe8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD,0x70,0x06); // select IRQ resource for Serial Port 4.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD,0xf0,0x02); // ART D clock source is 2 MHz (24 MHz / 12)

	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE,0x30,0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE,0x60,0x03); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE,0x61,0xe0); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE,0x70,0x0A); // select IRQ resource for Serial Port 5.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE,0xf0,0x02); // ART E clock source is 2 MHz (24 MHz / 12)


	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF,0x30,0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF,0x60,0x02); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF,0x61,0xe0); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF,0x70,0x0B); // select IRQ resource for Serial Port 6.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF,0xf0,0x02); // ART F clock source is 2 MHz (24 MHz / 12)
#else
	// 2e_4e
	if (NCT6106_REG_EFER == 0x2E) {
		Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1, (0x03|(0x00<<6)));
	} else if(NCT6106_REG_EFER == 0x4E) {
		Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1, (0x03|(0x01<<6)));
	} else {
		printf("error: not define port number.\n");
		return;
	}

	// IRQ Type and Polarity setting.
	// Must set 1 before  accessing Device IRQ Polarity Selection and Device IRQ TYPE Selection
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1, data|(0x01<<4));

	// Device IRQ Polarity Selection.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DIPS1, 0xFF);  // low level trigger
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DIPS2, 0xFF);  // low level trigger
	//data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DIPS1);
	//Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DIPS1,data|0x0C);//IRQ8~15 Polarity 
	//data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DIPS2);
	//Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DIPS2,data|0xB8);//IRQ0~7 Polarity 

	(*(volatile unsigned int*)0X90000E0010002010) = 0x0;// ps/2  LPC Polarity

	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS1, 0xDC); // MCLK  MDAT  KDAT KCLK LPT

	// ps/2
	// Device IRQ TYPE Selection  PS2
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS1, 
	data | (DITS_VAL_IRQ_TYPE_SELECT_LEVEL << DITS1_BIT_IRQ_TYPE_SELECT_KBC)
	|(DITS_VAL_IRQ_TYPE_SELECT_LEVEL << DITS1_BIT_IRQ_TYPE_SELECT_MOUSE));

	//data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS1);
	//Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS1, data&0xF3);// set kbc mouse IRQ type to Edge   

	// Multi Function Selection   PS2
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS1, data | ( 0x01 << 3) | (0x01<<2)); // MCLK  MDAT  KDAT KCLK

	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_ACPI, 0xE0);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_ACPI, 0xE0, data&(~0x04));//23.11 Logical Device A (ACPI)   Keyboard / Mouse swap enable  

	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_KBC, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_KBC, 0x60, 0x00); // select the first KBC I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_KBC, 0x61, 0x60); // select the first KBC I/O base address  60 
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_KBC, 0x62, 0x00); // select the second KBC I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_KBC, 0x63, 0x64); // select the second KBC I/O base address 64 
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_KBC, 0x70, 0x01); // select IRQ resource for KINT. (Keyboard interrupt)   01   
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_KBC, 0x72, 0x0C); // select IRQ resource for MINT. (PS/2 Mouse interrupt)
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_KBC, 0xF0, 0x83); // select IRQ resource for MINT. (PS/2 Mouse interrupt)   ps/2 

	// UARTB
	// Device IRQ TYPE Selection
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS1,
	data|(DITS_VAL_IRQ_TYPE_SELECT_LEVEL<< DITS1_BIT_IRQ_TYPE_SELECT_UARTB));
	// Disable UART B legacy mode for IRQ Selection
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1, data|(0x01<<0));
	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0x60, 0x02); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0x61, 0xf8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0x70, 0x03); // select IRQ resource for Serial Port 2.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0xf0, 0x02); // UART B clock source is 2 MHz (24 MHz / 12)

	// com 1 3 4 5 6 <<<<<<<<<<<<<<<<<<<<<<<<<<< start 
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS3);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS3, data|0x0E);// set uart C D E function 

	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_SFR);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_SFR, data&0xE7);// set SOUTC_P80_SEL, SOUTE_P80_SEL   0  1110 0111 

	// UART A B 
	// Device IRQ TYPE Selection  level type 
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS1, data|0x30);
	// Disable URAT A  B legacy mode for IRQ Selection ?
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1, data|0x03);

	// UART C D E F
	// Device IRQ TYPE Selection  level type 
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS2);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_DITS2, data|0x2C);
	// Disable URAT C D E F  legacy mode for IRQ Selection ? 
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO4);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO4, data|0x0F); 

	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA, 0x60, 0x03); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA, 0x61, 0xf8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA, 0x70, 0x04); // select IRQ resource for Serial Port 1.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTA, 0xf0, 0x02); // ART B clock source is 2 MHz (24 MHz / 12)

	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0x60, 0x02); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0x61, 0xf8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0x70, 0x03); // select IRQ resource for Serial Port 2.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTB, 0xf0, 0x02); // ART B clock source is 2 MHz (24 MHz / 12)


	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC, 0x60, 0x03); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC, 0x61, 0xe8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC, 0x70, 0x05); // select IRQ resource for Serial Port 3.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTC, 0xf0, 0x02); // ART B clock source is 2 MHz (24 MHz / 12)  


	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD, 0x60, 0x02); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD, 0x61, 0xe8); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD, 0x70, 0x06); // select IRQ resource for Serial Port 4.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTD, 0xf0, 0x02); // ART B clock source is 2 MHz (24 MHz / 12)  

	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE, 0x60, 0x03); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE, 0x61, 0xe0); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE, 0x70, 0x0A); // select IRQ resource for Serial Port 5.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTE, 0xf0, 0x02); // ART B clock source is 2 MHz (24 MHz / 12)  


	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF, 0x60, 0x02); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF, 0x61, 0xe0); // select IR I/O base address
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF, 0x70, 0x0B); // select IRQ resource for Serial Port 6.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_UARTF, 0xf0, 0x02); // ART B clock source is 2 MHz (24 MHz / 12)  
	// com 1 3 4 5 6>>>>>>>>>>>>>>>>>>>>>>>>>>>>end

	// Parallel port
	// Multi Function Selection
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_MFS1, data|(0x01<<4));
	// Disable PRT legacy mode for IRQ and DRQ Selection
	data = Nct6106d_read(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1);
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_GLOBAL, NCT6106_REG_GLOBAL_GO1, data|(0x01<<2));
	// Logical Configure
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_PRT, 0x30, 0x01); // The logical device is active.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_PRT, 0x60, 0x03); // select PRT I/O base address.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_PRT, 0x61, 0x78); // select PRT I/O base address.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_PRT, 0x70, 0x07); // select IRQ resource for PRT.
	Nct6106d_write(NCT6106_LOGICAL_DEV_NO_PRT, 0x74, 0x04); // bits select DRQ resource for PRT.
#endif
}

